<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //apply 改变this指向 
        
        function fn(x,y){
            console.log(this,x,y);
        }

        // 直接调用  
        // fn(); // this 会指向window

        // 通过 apply 调用 fn函数 
        // var obj = {
        //     name:"hello"
        // }
        // fn.apply(obj);
        // fn.apply(1111);

        // 和 call的区别 参数的传递 ；
        // call 方法 参数直接传递 
        // fn.call(obj,1,2);
        // apply方法 参数需要放在数组里传递 
        // fn.apply(obj,[10,20]);


        // 使用 apply 改变函数的this指向 

        // function fn(){
        //     // console.log(arguments);
        //     function fn2(){  // 不定参 
        //         console.log(arguments);
        //         console.log(this);
        //     }
        //     var obj = {
        //         myname:"名字"
        //     }
        //     // fn2.apply(obj)
        //     // fn2.call(obj)
        //     fn2.apply(obj,arguments); // 可以直接写数组作为参数 ；
        // }


        // fn(1,2,3,4); // 传实参 ，不定参： 参数的个数不确定 



        // 实现一个 apply 方法 

        Function.prototype.myApply = function(arg,args){
            // console.log(args);
            var argContext = arg || window;  // arg 传入的是 undefined或者是null  argContext 就是window
            // 如果传入的是 数字或者字符串 ;
            argContext = Object(argContext);
            // console.log(argContext);
            argContext.myfn = this;
            var res = argContext.myfn(...args);
            delete argContext.myfn;
            return res;
        }


        function fn(x,y,z){
            console.log(this,x,y,z);
        }

        var obj = {
            name:"修改this的对象"
        }

        fn.myApply(null,[1,2,3])


    </script>
</body>
</html>